package zack.project.domain.activity.service.partake;

import zack.project.domain.activity.adapter.repository.IActivityRepository;
import zack.project.domain.activity.model.aggregate.CreatePartakeOrderAggregate;
import zack.project.domain.activity.model.entity.*;
import zack.project.domain.activity.model.valobj.UserRaffleOrderStateVO;
import zack.project.types.enums.ResponseCode;
import zack.project.types.exception.AppException;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author A1793
 */

@Service
public class RaffleActivityPartakeService extends AbstractRaffleActivityPartake {

    private SimpleDateFormat dateFormatMonth = new SimpleDateFormat("yyyy-MM");
    private SimpleDateFormat dateFormatDay = new SimpleDateFormat("yyyy-MM-dd");

    public RaffleActivityPartakeService(IActivityRepository activityRepository) {
        super(activityRepository);
    }

    @Override
    protected UserRaffleOrderEntity buildUserRaffleOrder(String userId, Long activityId, Date currentDate) {

        ActivityEntity activityEntity = activityRepository.queryRaffleActivityByActivityId(activityId);

        return UserRaffleOrderEntity.builder()
                .userId(userId)
                .activityId(activityId)
                .activityName(activityEntity.getActivityName())
                .strategyId(activityEntity.getStrategyId())
                .orderId(RandomStringUtils.randomNumeric(12))
                .orderTime(currentDate)
                .orderState(UserRaffleOrderStateVO.create)
                .endTime(activityEntity.getEndDateTime())
                .build();

    }

    /**
     * 进行用户抽奖次数过滤(总账户，月账户，日账户是否有抽奖次数),构建活动和参与的聚合实体(先设置账户信息，后面会继续构建一笔未使用的抽奖单)
     * @param userId
     * @param activityId
     * @param currentDate
     * @return
     */
    @Override
    protected CreatePartakeOrderAggregate doFilterAccount(String userId, Long activityId, Date currentDate) {
        //根据活动id和用户id查找数据库表{raffle_activity_account}对应的活动总账户实体(有总次数，总次数余量，日次数，日次数余量，月次数，月次数余量)
        ActivityAccountEntity activityAccountEntity =
                activityRepository.queryActivityAccountByUserId(userId, activityId);
        if (activityAccountEntity == null || activityAccountEntity.getDayCountSurplus() <= 0) {
            throw new AppException(ResponseCode.ACCOUNT_QUOTA_ERROR.getCode(), ResponseCode.ACCOUNT_QUOTA_ERROR.getInfo());
        }
        /**
         * 通过传入的时间和定义的时间格式化器来获得当前的月份和号
         */
        String month = dateFormatMonth.format(currentDate);
        String day = dateFormatDay.format(currentDate);
        //根据当前月份和userId，activityId查找数据库表{raffle_activity_account_month}看是否有对应的月账户实体
        ActivityAccountMonthEntity activityAccountMonthEntity =
                activityRepository.queryActivityAccountMonthByUserId(userId, activityId, month);
        //有但月抽奖余量<=0则报错
        if (activityAccountMonthEntity != null && activityAccountMonthEntity.getMonthCountSurplus() <= 0) {
            throw new AppException(ResponseCode.ACCOUNT_MONTH_QUOTA_ERROR.getCode(), ResponseCode.ACCOUNT_MONTH_QUOTA_ERROR.getInfo());
        }
        //走到当前步骤说明已经存在月账户信息且却库存不为0 或者 本月不存在月账户
        boolean isExistMonthAccount = null != activityAccountMonthEntity;
        //根据总账户来创建当前月份的月账户
        if (!isExistMonthAccount) {
            activityAccountMonthEntity = ActivityAccountMonthEntity.builder()
                    .userId(activityAccountEntity.getUserId())
                    .activityId(activityAccountEntity.getActivityId())
                    .monthCount(activityAccountEntity.getMonthCount())
                    .monthCountSurplus(activityAccountEntity.getMonthCountSurplus()).
                    month(month)
                    .build();
        }

        ActivityAccountDayEntity activityAccountDayEntity =
                activityRepository.queryActivityAccountDayByUserId(userId, activityId, day);

        if (activityAccountDayEntity != null && activityAccountDayEntity.getDayCountSurplus() <= 0) {
            throw new AppException(ResponseCode.ACCOUNT_DAY_QUOTA_ERROR.getCode(), ResponseCode.ACCOUNT_DAY_QUOTA_ERROR.getInfo());
        }

        boolean isExistDayAccount = null != activityAccountDayEntity;
        //根据总账户创建当天的日账户
        if (!isExistDayAccount) {
            activityAccountDayEntity = ActivityAccountDayEntity.builder()
                    .userId(activityAccountEntity.getUserId())
                    .activityId(activityAccountEntity.getActivityId())
                    .dayCount(activityAccountEntity.getDayCount())
                    .dayCountSurplus(activityAccountEntity.getDayCountSurplus()).
                    day(day)
                    .build();
        }

        //创建参与活动的聚合实体:总账户，月账户，日账户，抽奖单，当前用户过滤阶段不构建抽奖单
        CreatePartakeOrderAggregate createPartakeOrderAggregate = new CreatePartakeOrderAggregate();
        createPartakeOrderAggregate.setUserId(userId);
        createPartakeOrderAggregate.setActivityId(activityId);
        createPartakeOrderAggregate.setActivityAccountEntity(activityAccountEntity);
        createPartakeOrderAggregate.setActivityAccountMonthEntity(activityAccountMonthEntity);
        createPartakeOrderAggregate.setExistAccountMonth(isExistMonthAccount);
        createPartakeOrderAggregate.setActivityAccountDayEntity(activityAccountDayEntity);
        createPartakeOrderAggregate.setExistAccountDay(isExistDayAccount);

        return createPartakeOrderAggregate;

    }

    public SimpleDateFormat getDateFormatDay() {
        return dateFormatDay;
    }

    public void setDateFormatDay(SimpleDateFormat dateFormatDay) {
        this.dateFormatDay = dateFormatDay;
    }

    public SimpleDateFormat getDateFormatMonth() {
        return dateFormatMonth;
    }

    public void setDateFormatMonth(SimpleDateFormat dateFormatMonth) {
        this.dateFormatMonth = dateFormatMonth;
    }
}
